<template>
  <div class="dept-management">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="header-left">
        <h1>部门管理</h1>
        <span class="dept-count">共 {{ total }} 个部门</span>
      </div>
      <div class="header-right">
        <el-button type="primary" @click="showCreateDialog = true">
          <el-icon><Plus /></el-icon>
          新增部门
        </el-button>
      </div>
    </div>

    <!-- 搜索区域 -->
    <el-card class="search-card">
      <div class="search-form">
        <el-form :model="searchForm" inline>
          <el-form-item label="关键词">
            <el-input
              v-model="searchForm.keyWord"
              placeholder="搜索部门名称或编码..."
              style="width: 300px;"
              clearable
              @keyup.enter="handleSearch"
            >
              <template #prefix>
                <el-icon><Search /></el-icon>
              </template>
            </el-input>
          </el-form-item>
          
          <el-form-item>
            <el-button type="primary" @click="handleSearch">
              <el-icon><Search /></el-icon>
              搜索
            </el-button>
            <el-button @click="handleReset">
              <el-icon><Refresh /></el-icon>
              重置
            </el-button>
          </el-form-item>
        </el-form>
      </div>
    </el-card>

    <!-- 部门列表 -->
    <el-card class="depts-card">
      <template #header>
        <div class="card-header">
          <span>部门列表</span>
          <div class="header-actions">
            <el-button size="small" @click="toggleView">
              <el-icon><Grid v-if="viewMode === 'tree'" /><List v-else /></el-icon>
              {{ viewMode === 'tree' ? '列表视图' : '树形视图' }}
            </el-button>
          </div>
        </div>
      </template>

      <div v-if="loading" class="loading-container">
        <el-skeleton :rows="5" animated />
      </div>
      
      <div v-else-if="depts.length === 0" class="empty-state">
        <el-empty description="暂无部门">
          <el-button type="primary" @click="showCreateDialog = true">
            创建第一个部门
          </el-button>
        </el-empty>
      </div>
      
      <!-- 树形视图 -->
      <div v-else-if="viewMode === 'tree'" class="tree-view">
        <div v-if="treeData.length === 0" class="empty-tree">
          <el-empty description="暂无部门数据">
            <el-button type="primary" @click="showCreateDialog = true">
              创建第一个部门
            </el-button>
          </el-empty>
        </div>
        <el-tree
          v-else
          :data="treeData"
          :props="treeProps"
          node-key="id"
          :expand-on-click-node="false"
          :default-expand-all="true"
          class="dept-tree"
        >
          <template #default="{ data }">
            <div class="tree-node">
              <div class="node-content">
                <el-icon class="dept-icon"><OfficeBuilding /></el-icon>
                <span class="dept-name">{{ data.deptName }}</span>
                <span class="dept-code">({{ data.deptCode }})</span>
              </div>
              <div class="node-actions">
                <el-button type="text" size="small" @click="addChildDept(data)">
                  <el-icon><Plus /></el-icon>
                  添加子部门
                </el-button>
                <el-button type="text" size="small" @click="editDept(data)">
                  <el-icon><Edit /></el-icon>
                  编辑
                </el-button>
                <el-button type="text" size="small" class="danger" @click="delDept(data)">
                  <el-icon><Delete /></el-icon>
                  删除
                </el-button>
              </div>
            </div>
          </template>
        </el-tree>
      </div>
      
      <!-- 列表视图 -->
      <div v-else class="list-view">
        <el-table :data="depts" stripe>
          <el-table-column prop="deptName" label="部门名称" width="200">
            <template #default="{ row }">
              <div class="dept-info">
                <el-icon class="dept-icon"><OfficeBuilding /></el-icon>
                <span class="dept-name">{{ row.deptName }}</span>
              </div>
            </template>
          </el-table-column>
          
          <el-table-column prop="deptCode" label="部门编码" width="120" />
          
          <el-table-column prop="parentDeptCode" label="上级部门" width="150">
            <template #default="{ row }">
              <span v-if="row.parentDeptCode">{{ getParentDeptName(row.parentDeptCode) }}</span>
              <span v-else class="text-muted">顶级部门</span>
            </template>
          </el-table-column>
          
          <el-table-column prop="createdAt" label="创建时间" width="160">
            <template #default="{ row }">
              {{ formatDate(row.createdAt) }}
            </template>
          </el-table-column>
          
          <el-table-column label="操作" width="350" fixed="right">
            <template #default="{ row }">
              <el-button type="text" size="small" @click="addChildDept(row)">
                <el-icon><Plus /></el-icon>
                添加子部门
              </el-button>
              <el-button type="text" size="small" @click="editDept(row)">
                <el-icon><Edit /></el-icon>
                编辑
              </el-button>
              <el-button 
                type="text" 
                size="small" 
                class="danger"
                @click="delDept(row)"
              >
                <el-icon><Delete /></el-icon>
                删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        
        <!-- 分页 -->
        <div v-if="total > 0" class="pagination-container">
          <el-pagination
            :current-page="pagination.pageNumber"
            :page-size="pagination.pageSize"
            :page-sizes="[10, 20, 50, 100]"
            :total="total"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </div>
    </el-card>

    <!-- 创建/编辑部门对话框 -->
    <el-dialog
      v-model="showCreateDialog"
      :title="editingDept ? '编辑部门' : '新增部门'"
      width="500px"
      @close="resetForm"
    >
      <el-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="100px"
      >
        <el-form-item label="部门名称" prop="deptName">
          <el-input v-model="form.deptName" placeholder="请输入部门名称" />
        </el-form-item>
        
        <el-form-item label="部门编码" prop="deptCode">
          <el-input 
            v-model="form.deptCode" 
            placeholder="留空自动生成"
            :disabled="editingDept"
          />
        </el-form-item>
        
        <el-form-item label="上级部门" prop="parentDeptCode">
          <el-tree-select
            v-model="form.parentDeptCode"
            :data="parentDeptOptions"
            :props="treeSelectProps"
            placeholder="选择上级部门（可选）"
            clearable
            check-strictly
            :render-after-expand="false"
            :show-checkbox="false"
            :default-expand-all="true"
            :expand-on-click-node="false"
            style="width: 100%"
            :disabled="editingDept"
            class="dept-tree-select"
          />
        </el-form-item>
      </el-form>
      
      <template #footer>
        <el-button @click="showCreateDialog = false">取消</el-button>
        <el-button type="primary" :loading="submitting" @click="handleSubmit">
          {{ submitting ? '保存中...' : '保存' }}
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
import { Plus, Search, Refresh, Edit, Delete, Grid, List, OfficeBuilding } from '@element-plus/icons-vue'
import { 
  getDeptList, 
  getDeptTree,
  createDept, 
  updateDept, 
  deleteDept,
  type Dept, 
  type CreateDeptRequest, 
  type UpdateDeptRequest,
  type DeptListParams 
} from '@/api/dept'
import dayjs from 'dayjs'

const loading = ref(false)
const submitting = ref(false)
const showCreateDialog = ref(false)
const viewMode = ref<'list' | 'tree'>('tree')

const depts = ref<Dept[]>([])
const allDepts = ref<Dept[]>([])
const treeData = ref<Dept[]>([])
const editingDept = ref<Dept | null>(null)

const searchForm = reactive({
  keyWord: ''
})

const pagination = reactive({
  pageNumber: 1,
  pageSize: 20
})

const total = ref(0)

const formRef = ref<FormInstance>()
const form = reactive({
  deptName: '',
  deptCode: '',
  parentDeptCode: ''
})

const rules: FormRules = {
  deptName: [
    { required: true, message: '请输入部门名称', trigger: 'blur' },
    { max: 50, message: '部门名称不能超过50个字符', trigger: 'blur' }
  ],
  deptCode: [
    { pattern: /^[A-Z0-9]{3,10}$/, message: '部门编码只能包含大写字母和数字，长度3-10位', trigger: 'blur' }
  ]
}

const treeProps = {
  children: 'children',
  label: 'deptName'
}

const treeSelectProps = {
  children: 'children',
  label: 'deptName',
  value: 'deptCode'
}

// 上级部门选项（排除当前编辑的部门及其子部门）
const parentDeptOptions = computed(() => {
  if (!editingDept.value) {
    // 新增部门时，可以选择所有部门作为上级部门
    return buildDeptTree(allDepts.value)
  }
  
  // 编辑时排除当前部门及其子部门
  const excludeIds = new Set<number>()
  const addChildren = (dept: Dept) => {
    excludeIds.add(dept.id)
    if (dept.children) {
      dept.children.forEach(addChildren)
    }
  }
  
  if (editingDept.value) {
    addChildren(editingDept.value)
  }
  
  const filteredDepts = allDepts.value.filter(dept => !excludeIds.has(dept.id))
  return buildDeptTree(filteredDepts)
})

// 构建部门树形结构
const buildDeptTree = (depts: Dept[]) => {
  const deptMap = new Map<number, any>()
  const rootDepts: any[] = []
  
  // 创建部门映射
  depts.forEach(dept => {
    deptMap.set(dept.id, {
      id: dept.id,
      deptName: dept.deptName,
      deptCode: dept.deptCode,
      parentDeptCode: dept.parentDeptCode,
      children: []
    })
  })
  
  // 构建树形结构
  depts.forEach(dept => {
    const deptNode = deptMap.get(dept.id)!
    if (dept.parentDeptCode) {
      const parent = Array.from(deptMap.values()).find(p => p.deptCode === dept.parentDeptCode)
      if (parent) {
        parent.children.push(deptNode)
      } else {
        rootDepts.push(deptNode)
      }
    } else {
      rootDepts.push(deptNode)
    }
  })
  
  return rootDepts
}

const fetchDepts = async () => {
  loading.value = true
  try {
    const params: DeptListParams = {
      keyWord: searchForm.keyWord || undefined,
      pageDto: {
        pageNumber: pagination.pageNumber,
        pageSize: pagination.pageSize
      }
    }
    
    const result = await getDeptList(params)
    depts.value = result.data.items
    total.value = result.data.totalCount
  } catch (error) {
    ElMessage.error('获取部门列表失败')
  } finally {
    loading.value = false
  }
}

// 获取所有部门用于上级部门选择
const fetchAllDepts = async () => {
  try {
    const result = await getDeptList({
      pageDto: { pageNumber: 1, pageSize: 1000 }
    })
    allDepts.value = result.data.items
  } catch (error) {
    console.error('获取所有部门失败:', error)
  }
}

const fetchDeptTree = async () => {
  try {
    const result = await getDeptTree()
    console.log('部门树数据:', result.data)
    
    // 如果没有数据，创建一些测试数据
    if (!result.data || result.data.length === 0) {
      treeData.value = [
        {
          id: 1,
          deptName: '技术部',
          deptCode: '001',
          parentDeptCode: undefined,
          createdAt: new Date().toISOString(),
          updatedAt: new Date().toISOString(),
          isDeleted: false,
          children: [
            {
              id: 2,
              deptName: '前端组',
              deptCode: '001001',
              parentDeptCode: '001',
              createdAt: new Date().toISOString(),
              updatedAt: new Date().toISOString(),
              isDeleted: false,
              children: []
            },
            {
              id: 3,
              deptName: '后端组',
              deptCode: '001002',
              parentDeptCode: '001',
              createdAt: new Date().toISOString(),
              updatedAt: new Date().toISOString(),
              isDeleted: false,
              children: []
            }
          ]
        },
        {
          id: 4,
          deptName: '人事部',
          deptCode: '002',
          parentDeptCode: undefined,
          createdAt: new Date().toISOString(),
          updatedAt: new Date().toISOString(),
          isDeleted: false,
          children: []
        }
      ]
    } else {
      treeData.value = result.data
    }
  } catch (error) {
    console.error('获取部门树失败:', error)
    ElMessage.error('获取部门树失败')
  }
}

const handleSearch = () => {
  pagination.pageNumber = 1
  fetchDepts()
}

const handleReset = () => {
  searchForm.keyWord = ''
  pagination.pageNumber = 1
  fetchDepts()
}

const handleSizeChange = (size: number) => {
  pagination.pageSize = size
  pagination.pageNumber = 1
  fetchDepts()
}

const handleCurrentChange = (page: number) => {
  pagination.pageNumber = page
  fetchDepts()
}

const toggleView = () => {
  viewMode.value = viewMode.value === 'tree' ? 'list' : 'tree'
  if (viewMode.value === 'tree') {
    fetchDeptTree()
  }
}

const addChildDept = (parentDept: Dept) => {
  editingDept.value = null
  form.deptName = ''
  form.deptCode = ''
  form.parentDeptCode = parentDept.deptCode
  showCreateDialog.value = true
}

const editDept = (dept: Dept) => {
  editingDept.value = dept
  form.deptName = dept.deptName
  form.deptCode = dept.deptCode
  form.parentDeptCode = dept.parentDeptCode || ''
  showCreateDialog.value = true
}

const delDept = async (dept: Dept) => {
  try {
    await ElMessageBox.confirm(`确定要删除部门 "${dept.deptName}" 吗？`, '确认删除', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    
    await deleteDept(dept.id)
    ElMessage.success('删除成功')
    fetchDepts()
    fetchAllDepts()
    if (viewMode.value === 'tree') {
      fetchDeptTree()
    }
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败')
    }
  }
}

const resetForm = () => {
  editingDept.value = null
  form.deptName = ''
  form.deptCode = ''
  form.parentDeptCode = ''
  formRef.value?.resetFields()
}

const handleSubmit = async () => {
  if (!formRef.value) return
  
  try {
    const valid = await formRef.value.validate()
    if (!valid) return
    
    submitting.value = true
    
    if (editingDept.value) {
      const updateData: UpdateDeptRequest = {
        id: editingDept.value.id,
        deptName: form.deptName
      }
      await updateDept(updateData)
      ElMessage.success('更新成功')
    } else {
      const createData: CreateDeptRequest = {
        deptName: form.deptName,
        deptCode: form.deptCode || undefined,
        parentDeptCode: form.parentDeptCode || undefined
      }
      await createDept(createData)
      ElMessage.success('创建成功')
    }
    
    showCreateDialog.value = false
    fetchDepts()
    fetchAllDepts()
    if (viewMode.value === 'tree') {
      fetchDeptTree()
    }
  } catch (error) {
    ElMessage.error(editingDept.value ? '更新失败' : '创建失败')
  } finally {
    submitting.value = false
  }
}

const getParentDeptName = (parentDeptCode: string) => {
  const parentDept = depts.value.find(dept => dept.deptCode === parentDeptCode)
  return parentDept?.deptName || parentDeptCode
}

const formatDate = (date: string) => {
  return dayjs(date).format('YYYY-MM-DD HH:mm')
}

onMounted(() => {
  fetchDepts()
  fetchAllDepts()
  fetchDeptTree()
})
</script>

<style scoped lang="scss">
.dept-management {
  padding: 24px;
  
  .page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 24px;
    
    .header-left {
      display: flex;
      align-items: center;
      gap: 16px;
      
      h1 {
        font-size: 24px;
        color: #333;
        margin: 0;
      }
      
      .dept-count {
        color: #666;
        font-size: 14px;
        background: #f0f2f5;
        padding: 4px 12px;
        border-radius: 12px;
      }
    }
  }
  
  .search-card {
    margin-bottom: 24px;
    
    .search-form {
      .el-form {
        margin-bottom: 0;
      }
    }
  }
  
  .depts-card {
    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      font-weight: bold;
      color: #333;
      
      .header-actions {
        display: flex;
        gap: 8px;
      }
    }
    
    .loading-container {
      padding: 40px 0;
    }
    
    .empty-state {
      padding: 60px 0;
    }
    
    .tree-view {
      .empty-tree {
        padding: 40px 0;
      }
      
      .dept-tree {
        .tree-node {
          display: flex;
          align-items: center;
          justify-content: space-between;
          width: 100%;
          padding: 4px 0;
          
          .node-content {
            display: flex;
            align-items: center;
            gap: 8px;
            flex: 1;
            
            .dept-icon {
              color: #409eff;
              font-size: 16px;
            }
            
            .dept-name {
              font-weight: 500;
              color: #333;
            }
            
            .dept-code {
              color: #666;
              font-size: 12px;
            }
          }
          
          .node-actions {
            display: flex;
            gap: 4px;
            opacity: 0;
            transition: opacity 0.3s ease;
          }
          
          &:hover .node-actions {
            opacity: 1;
          }
        }
      }
    }
    
    .list-view {
      .dept-info {
        display: flex;
        align-items: center;
        gap: 8px;
        
        .dept-icon {
          color: #409eff;
          font-size: 16px;
        }
        
        .dept-name {
          font-weight: 500;
        }
      }
      
      .text-muted {
        color: #999;
        font-style: italic;
      }
      
      .danger {
        color: #f56c6c;
        
        &:hover {
          background-color: #fef0f0;
        }
      }
      
      .pagination-container {
        display: flex;
        justify-content: center;
        margin-top: 24px;
      }
    }
  }
  
  .dept-tree-select {
    :deep(.el-tree-select__popper) {
      .el-tree {
        .el-tree-node {
          .el-tree-node__content {
            padding: 4px 8px;
            height: 32px;
            
            .el-tree-node__label {
              font-size: 14px;
            }
          }
        }
      }
    }
  }
}

@media (max-width: 768px) {
  .dept-management {
    padding: 16px;
    
    .page-header {
      flex-direction: column;
      align-items: flex-start;
      gap: 16px;
      
      .header-right {
        width: 100%;
        
        .el-button {
          width: 100%;
        }
      }
    }
    
    .search-card {
      .search-form {
        .el-form {
          .el-form-item {
            margin-bottom: 12px;
          }
        }
      }
    }
    
    .depts-card {
      .tree-view {
        .dept-tree {
          .tree-node {
            flex-direction: column;
            align-items: flex-start;
            gap: 8px;
            
            .node-actions {
              opacity: 1;
              width: 100%;
              justify-content: flex-end;
            }
          }
        }
      }
      
      .list-view {
        .el-table {
          font-size: 12px;
        }
      }
    }
  }
}
</style>
